/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.web.struts;

import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.util.ResponseUtils;

public class LinkTag extends org.apache.struts.taglib.html.LinkTag
{

    private StringBuffer hrefURL;


    public LinkTag()
    {
        hrefURL = new StringBuffer();
    }

    public int doStartTag()
        throws JspException
    {
        if(linkName != null)
        {
            StringBuffer results = new StringBuffer("<a name=\"");
            results.append(linkName);
            results.append("\">");
            return 2;
        }
        Map params = RequestUtils.computeParameters(pageContext, paramId, paramName, paramProperty, paramScope, name, property, scope, transaction);
        String url = null;
        try
        {
            url = RequestUtils.computeURL(pageContext, forward, href, page, params, anchor, false);
        }
        catch(MalformedURLException e)
        {
            RequestUtils.saveException(pageContext, e);
            throw new JspException(messages.getMessage("rewrite.url", e.toString()));
        }
        hrefURL = new StringBuffer("<a href=\"");
        hrefURL.append(url);
        text = null;
        return 2;
    }

    public void addRequestParameter(String name, String value)
    {
        boolean question = hrefURL.toString().indexOf('?') >= 0;
        if(question)
            hrefURL.append('&');
        else
            hrefURL.append('?');
        hrefURL.append(name);
        hrefURL.append('=');
        hrefURL.append(URLEncoder.encode(value));
    }

    public int doEndTag()
        throws JspException
    {
        hrefURL.append("\"");
        if(target != null)
        {
            hrefURL.append(" target=\"");
            hrefURL.append(target);
            hrefURL.append("\"");
        }
        hrefURL.append(prepareStyles());
        hrefURL.append(prepareEventHandlers());
        hrefURL.append(">");
        if(text != null)
            hrefURL.append(text);
        hrefURL.append("</a>");
        ResponseUtils.write(pageContext, hrefURL.toString());
        return 6;
    }

    public void release()
    {
        super.release();
        forward = null;
        href = null;
        name = null;
        property = null;
        target = null;
    }

    protected String hyperlink()
        throws JspException
    {
        String href = this.href;
        if(property != null && name == null)
            throw new JspException(messages.getMessage("getter.name"));
        if(name == null)
            return href;
        Object bean = pageContext.findAttribute(name);
        if(bean == null)
            throw new JspException(messages.getMessage("getter.bean", name));
        Map map = null;
        if(property == null)
            try
            {
                map = (Map)bean;
            }
            catch(ClassCastException e)
            {
                throw new JspException(messages.getMessage("linkTag.type"));
            }
        else
            try
            {
                map = (Map)PropertyUtils.getProperty(bean, property);
                if(map == null)
                    throw new JspException(messages.getMessage("getter.property", property));
            }
            catch(IllegalAccessException e)
            {
                throw new JspException(messages.getMessage("getter.access", property, name));
            }
            catch(InvocationTargetException e)
            {
                Throwable t = e.getTargetException();
                throw new JspException(messages.getMessage("getter.result", property, t.toString()));
            }
            catch(ClassCastException e)
            {
                throw new JspException(messages.getMessage("linkTag.type"));
            }
            catch(NoSuchMethodException e)
            {
                throw new JspException(messages.getMessage("getter.method", property, name));
            }
        StringBuffer sb = new StringBuffer(href);
        boolean question = href.indexOf("?") >= 0;
        for(Iterator keys = map.keySet().iterator(); keys.hasNext();)
        {
            String key = (String)keys.next();
            Object value = map.get(key);
            if(value instanceof String[])
            {
                String values[] = (String[])value;
                for(int i = 0; i < values.length; i++)
                {
                    if(question)
                    {
                        sb.append('&');
                    } else
                    {
                        sb.append('?');
                        question = true;
                    }
                    sb.append(key);
                    sb.append('=');
                    sb.append(URLEncoder.encode(values[i]));
                }

            } else
            {
                if(question)
                {
                    sb.append('&');
                } else
                {
                    sb.append('?');
                    question = true;
                }
                sb.append(key);
                sb.append('=');
                sb.append(URLEncoder.encode(value.toString()));
            }
        }

        return sb.toString();
    }

}